package lj.netty;

import cn.hutool.core.lang.Opt;
import cn.hutool.log.StaticLog;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import lombok.Data;
import ntd.util.UtilCatch;

/**
 * netty - tcp 使用封装
 */
@Data
public class ComNettyTcp extends ComAbsNettyTcp implements ComNetty {

    //是一个启动NIO服务的辅助启动类
    ServerBootstrap serverBootstrap = new ServerBootstrap();

    public ComNettyTcp(int port) {
        this.port = port;
    }

    /**
     * 启动监听
     */
    public void start() {
        serverBootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)  // 这里告诉Channel如何接收新的连接
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) {
                        ChannelPipeline pipeline = ch.pipeline();
                        // 配置十分钟无消息则掉线
                        pipeline.addLast(new ReadTimeoutHandler(60 * 10));
                        // 分包器
                        Opt.ofNullable(ljNettyInitContext.getLJCNettyListen()).ifPresent(ljcNettyListen -> pipeline.addLast(ljcNettyListen.struct()));
                        // 监听器
                        pipeline.addLast(ljNettyInitContext.getChannelHandlerCommon());
                    }
                });
        serverBootstrap.option(ChannelOption.SO_BACKLOG, 128);
        serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);

        UtilCatch.tryCatchNoRes(() -> {
            ChannelFuture sync = serverBootstrap.bind(port).sync();// 绑定端口，开始接收进来的连接
            StaticLog.info("TCP服务端[{}]启动成功", port);
            sync.channel().closeFuture().sync();
            StaticLog.info("TCP服务端[{}]关闭成功", port);
        });
    }

    @Override
    public boolean conn() {
        StaticLog.info("服务端无需重连...");
        return true;
    }
}
